/*
 * String.cpp
 *
 *  Created on: 2020年12月2日
 *      Author: san
 */

#include "String.h"

std::allocator<char> String::alloc;

String::String(const String &s)
{
	// 拷贝构造函数
	std::cout << "String::String(const String &s)" << std::endl;
	auto new_data = alloc_n_copy(s.begin, s.end);
	begin = new_data.first;
	end = new_data.second;
}

String::String(String &&s) noexcept : begin(std::move(s.begin)), end(std::move(s.end))
{
	// 移动构造函数
	std::cout << "String::String(String &&s)" << std::endl;
	s.begin = s.end = nullptr;
}

String &String::operator =(const String &s)
{
	std::cout << "String &String::operator =(const String &s)" << std::endl;
	auto new_data = alloc_n_copy(s.begin, s.end);
	free();
	begin = new_data.first;
	end = new_data.second;
}

String &String::operator=(String &&s) noexcept
{
	std::cout << "String &String::operator =(const String &s)" << std::endl;
	begin = std::move(s.begin);
	end = std::move(s.end);
	s.begin = s.end = nullptr;
}

std::ostream &operator <<(std::ostream &os, const String &s)
{
	// 输出运算符的重载
	for (auto p = s.begin; p != s.end; ++p)
	{
		os << *p;
	}
}

std::pair<char*, char*> String::alloc_n_copy (const char* beg, const char* end)
{
    auto str = alloc.allocate (end - beg);
    return {str, std::uninitialized_copy(beg, end, str)};
}

String::String(const char *s)
{
	auto new_data = alloc_n_copy(s, s + strlen(s));
	begin = new_data.first;
	end = new_data.second;
}

void String::free()
{
	if (begin)
	{
		for (auto p = end; p != begin;)
		{
			alloc.destroy(--p);
		}
//		std::cout << std::endl << "destroyed successed" << std::endl;
		alloc.deallocate(begin, size());
//		std::cout << "deallocate successed" << std::endl;
	}
}

String::~String() {
	// TODO Auto-generated destructor stub
	free();
}

